home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / prolog / sbprolog / v3 / sim.lha / sim / load_work.c < prev    next >
C/C++ Source or Header  |  1991-05-21  |  11KB  |  354 lines

  1. /************************************************************************
  2. *                                    *
  3. * The SB-Prolog System                            *
  4. * Copyright SUNY at Stony Brook, 1986; University of Arizona, 1987    *
  5. *                                    *
  6. ************************************************************************/
  7.  
  8. /*-----------------------------------------------------------------
  9. SB-Prolog is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY.  No author or distributor
  11. accepts responsibility to anyone for the consequences of using it
  12. or for whether it serves any particular purpose or works at all,
  13. unless he says so in writing.  Refer to the SB-Prolog General Public
  14. License for full details.
  15.  
  16. Everyone is granted permission to copy, modify and redistribute
  17. SB-Prolog, but only under the conditions described in the
  18. SB-Prolog General Public License.   A copy of this license is
  19. supposed to have been given to you along with SB-Prolog so you
  20. can know your rights and responsibilities.  It should be in a
  21. file named COPYING.  Among other things, the copyright notice
  22. and this notice must be preserved on all copies. 
  23. ------------------------------------------------------------------ */
  24. /* load_work.c */
  25.  
  26. #define DEBUG_OVERFLOW
  27. /*
  28. #define DEBUG_NAMESTRING
  29. #define DEBUG_LOADWORK
  30. */
  31.  
  32. #include "sim.h"
  33. #include "aux.h"
  34. /* #include <stdio,h> */
  35. #define ALIGN(type,ptr)  ptr = (type)(((LONG)ptr + 3) & 0xfffffffc)
  36.  
  37. /************************************************************************
  38. *                                                                       *
  39. *  The hash function uses the arity and character string associated     *
  40. *  with a predicate, constant, or structure to find the proper bucket   *
  41. *  (a bucket is a linked list within the pcs table) to insert or locate *
  42. *  pcs entries.                                                         *
  43. *                                                                       *
  44. ************************************************************************/
  45.  
  46. int hash(name, length, arity)  /* hashing function on name,returning a */
  47. CHAR_PTR name;                 /* bucket number in the hash table      */
  48. WORD     length;
  49. BYTE     arity;
  50. {
  51.    int bucknum;
  52.  
  53.    bucknum = arity + 1;
  54.    if (length > 0) {              /* first */
  55.       bucknum = bucknum + *name;
  56.       if (length > 1) {           /* last */
  57.          bucknum = (bucknum << 2) + *(name + length - 1);
  58.          if (length > 2) {        /* middle */
  59.             bucknum = (bucknum << 2) + *(name + length / 2);
  60.             if (length > 3)
  61.                bucknum = (bucknum << 2) + *(name+(length / 2) - 1);
  62.          }
  63.       }
  64.    }
  65.    return abs(bucknum % BUCKET_CHAIN);
  66.  
  67. }  /* end of hash */
  68.  
  69. /******************************************************************************/
  70.  
  71. LONG_PTR search(name, length, arity, hash_ptr)
  72. CHAR_PTR name;
  73. BYTE     arity;
  74. WORD     length;
  75. LONG_PTR hash_ptr;
  76. {
  77.    PSC_REC_PTR psc_ptr;
  78.    unsigned short i;
  79.    struct booleans {
  80.       unsigned eq   : 1;
  81.       unsigned stop : 1;
  82.    } flag;
  83.  
  84.    flag.eq   = FALSE;
  85.    flag.stop = FALSE;
  86.  
  87. #ifdef  DEBUG_LOADWORK
  88.    printf("search: name = %s   len = %d   arity = %d  ", name, length, arity);
  89.    printf("hash = %08x\n", hash_ptr);
  90. #endif
  91.  
  92.    while (!ISFREE(hash_ptr) && flag.stop == FALSE) {
  93.       hash_ptr = (LONG_PTR)FOLLOW(hash_ptr);    /* pointer to pair */
  94.       psc_ptr = (PSC_REC_PTR)FOLLOW(hash_ptr);  /* pointer to psc record */
  95.  
  96. #ifdef  DEBUG_LOADWORK
  97.       printf("   hash_ptr  %08x   psc_ptr  %08x     *hash_ptr  %08x  \n",
  98.              hash_ptr, psc_ptr, *hash_ptr);
  99. #endif
  100.  
  101.       if (arity  == GET_ARITY(psc_ptr) && length == GET_LENGTH(psc_ptr)) {
  102.          flag.eq = TRUE;
  103.          for (i = 0; i < length && flag.eq == TRUE; i++)
  104.             if (*(name + i) != *(GET_NAME(psc_ptr) + i))
  105.                flag.eq = FALSE;
  106.       }
  107.       if (flag.eq == TRUE)
  108.      flag.stop = TRUE;
  109.       else hash_ptr++;
  110.   }
  111.  
  112.   return hash_ptr;
  113.  
  114. }  /* end of search */
  115.  
  116. /******************************************************************************/
  117.  
  118. LONG_PTR insert_temp(name, length, hash_ptr)
  119. CHAR_PTR name;
  120. WORD     length;
  121. LONG_PTR hash_ptr;
  122. {
  123.    PSC_REC_PTR       psc_ptr;
  124.    LONG_PTR          new_pair, stack_top, heap_top;
  125.    register CHAR_PTR threg;
  126.    LONG              i;
  127.  
  128.    /* check for heap overflow */
  129.    stack_top = (breg < ereg) ? breg : ereg - ENV_SIZE(cpreg);
  130.    heap_top  = hreg + 4 + ((length + 3) >> 2);
  131.    if (stack_top < heap_top) {
  132.       /* garbage_collection("insert_temp"); */
  133.       if (stack_top < heap_top)    /* still too full */
  134.          quit("Heap overflow\n");
  135.    }
  136.    new_pair = hreg++;
  137.    FOLLOW(hash_ptr) = (LONG)new_pair;
  138.    PUSHTRAIL((LONG)hash_ptr);         /* trail for backtracking */
  139.    MAKE_FREE(LONG, *hreg);            /* 2nd of pair free */
  140.    FOLLOW(new_pair) = (LONG)++hreg;   /* 1st of pair points to psc_rec */
  141.    psc_ptr= (PSC_REC_PTR)hreg;        /* psc_ptr points to the psc entry */
  142.    hreg += 2;                         /* reserve the space on the heap */
  143.                                       /*   NO EP FIELD */
  144.  
  145.    /* make nameptr point to next available space on heap */
  146.  
  147.    GET_ETYPE(psc_ptr)  = T_ORDI;
  148.    GET_ARITY(psc_ptr)  = 0;
  149.    GET_LENGTH(psc_ptr) = length;
  150.   /* GET_NAME(psc_ptr) = name; */
  151.  
  152.    threg = (CHAR_PTR)hreg;
  153.    GET_NAME(psc_ptr) = threg;     /* copy name, since might write over it !! */
  154.    for (i = 0; i < length; i++)
  155.       *threg++ = *name++;
  156.  
  157.    hreg = (LONG_PTR)threg;
  158.    ALIGN(LONG_PTR, hreg);
  159.  
  160.    return new_pair;
  161.  
  162. }  /* end of insert_temp */
  163.  
  164. /******************************************************************************/
  165.  
  166. LONG_PTR insert_perm(name, length, arity, hash_ptr)
  167. CHAR_PTR name;
  168. BYTE     arity;
  169. WORD     length;
  170. LONG_PTR hash_ptr;
  171. {
  172.    PSC_REC_PTR   psc_ptr;
  173.    LONG_PTR      new_pair;
  174.    register LONG i;
  175.  
  176.    ALIGN(CHAR_PTR, curr_fence);
  177.  
  178.    new_pair = (LONG_PTR)curr_fence;
  179.    FOLLOW(hash_ptr) = (LONG)new_pair;           /* prev link to here */
  180.    curr_fence += 4;                             /* point to 2nd of pair */
  181.    MAKE_FREE(LONG_PTR,*(LONG_PTR *)curr_fence); /* set 2nd free */
  182.  
  183. #ifdef DEBUG_LOADWORK
  184.    printf("insert_perm %8x %8x\n", curr_fence, *(LONG_PTR)curr_fence);
  185. #endif
  186.  
  187.    curr_fence += 4;                             /* where we'll put psc_rec */
  188.    FOLLOW(new_pair) = (LONG)curr_fence;         /* set 1st to pt to psc_rec */
  189.    psc_ptr= (PSC_REC_PTR)curr_fence;            /* psc_ptr points there too */
  190.    curr_fence += 12;                            /* 12 bytes for psc_rec */
  191.  
  192.    GET_ETYPE(psc_ptr)  = T_ORDI;
  193.    GET_ARITY(psc_ptr)  = arity;
  194.    GET_LENGTH(psc_ptr) = length;
  195.    GET_NAME(psc_ptr)   = curr_fence;
  196.  
  197.    for (i = 0; i < length; i++)
  198.       *curr_fence++ = *name++;
  199.  
  200.    ALIGN(CHAR_PTR, curr_fence);
  201.  
  202.    if (curr_fence >= max_fence) {
  203. #ifdef DEBUG_OVERFLOW
  204.       printf("Overflow in \"insert_perm\" curr_fence = %08x max_fence = %08x\n",
  205.              curr_fence, max_fence);
  206. #endif
  207.       quit("Program area overflow\n");
  208.    }
  209.  
  210.    return new_pair;
  211.  
  212. }  /*  end of insert_perm */
  213.  
  214. /******************************************************************************/
  215.  
  216. LONG_PTR insert(name, length, arity, perm)
  217. CHAR_PTR name;
  218. WORD     length;
  219. BYTE     arity;
  220. BYTE_PTR perm;
  221. {
  222.    int      bucket_no;
  223.    LONG_PTR temp_ptr, perm_ptr, perm_hashptr, temp_hashptr, ret_ptr;
  224.  
  225.    bucket_no = hash(name, length, arity);
  226.    perm_hashptr = (LONG_PTR)&hash_table[bucket_no][PERM];
  227.  
  228. #ifdef DEBUG_LOADWORK
  229.    printf("insert: name = %s   len = %d   arity = %d  ", name, length, arity);
  230.    printf("bucket = %d  perm = %08x  hash = %08x\n",
  231.       bucket_no, perm_hashptr, *perm_hashptr);
  232. #endif
  233.  
  234.    perm_ptr = search(name, length, arity, perm_hashptr);
  235.    if (!ISFREE(perm_ptr)) {   /* found perm psc record */
  236.       if (!(*perm))
  237.          *perm = PERM;        /* set perm flag parameter */
  238.       return perm_ptr;        /* return permanent */
  239.    }
  240.  
  241.    temp_hashptr = (LONG_PTR)&hash_table[bucket_no][TEMP];  /* look for temp */
  242.    temp_ptr = search(name, length, arity, temp_hashptr);
  243.    if (!ISFREE(temp_ptr)) {  /* found temp psc record */
  244.       if (!(*perm))          /* temporary wanted */
  245.          return temp_ptr;    /* return ptr to psc record */
  246.       else {                 /* Perm wanted - convert temp to perm */
  247.          /*printf("cvting temp to perm: %c %d %d\n", *name, length, arity);*/
  248.          perm_ptr = insert_perm(name, length, arity, perm_ptr);
  249.          FOLLOW(temp_ptr) = FOLLOW(perm_ptr);
  250.          return perm_ptr;
  251.       }
  252.     } else {                 /* Insert constant where indicated */
  253.       if (*perm)
  254.          return insert_perm(name, length, arity, perm_ptr);
  255.       else
  256.          return insert_temp(name, length, temp_ptr);
  257.    }
  258. }  /* end of insert */
  259.  
  260. /************************************?????????????????????*********/
  261.  
  262. set_temp_ep(psc_ptr, ep)
  263. PSC_REC_PTR psc_ptr;
  264. {
  265.    if (ep >= 0) {
  266.       GET_ETYPE(psc_ptr) = T_TEMP_PRED;
  267.       GET_EP(psc_ptr) = (LONG_PTR)ep;
  268.    }
  269. }
  270.  
  271. /************************************?????????????????????*********/
  272.  
  273. set_real_ep(psc_ptr, base)
  274. PSC_REC_PTR psc_ptr;
  275. CHAR_PTR    base;
  276. {
  277.    if (GET_ETYPE(psc_ptr) == T_TEMP_PRED) {
  278.       GET_EP(psc_ptr) = (LONG_PTR)(base + (int)GET_EP(psc_ptr));  /*???*/
  279.       GET_ETYPE(psc_ptr) = T_PRED;
  280.    }
  281. }
  282.  
  283. /************************************?????????????????????*********/
  284.  
  285. /*
  286. set_file_ptr(psc_ptr, file_ptr)
  287. PSC_REC_PTR psc_ptr;
  288. FILE        *file_ptr;
  289. {
  290.    GET_ETYPE(psc_ptr) = T_FILE;
  291.    GET_EP(psc_ptr) = (WORD_PTR)(file_ptr);
  292. }
  293. */
  294.  
  295. /************************************?????????????????????*********/
  296.  
  297. /*
  298. unset_file_ptr(psc_ptr)
  299. PSC_REC_PTR psc_ptr;
  300. {
  301.    GET_ETYPE(psc_ptr) = T_ORDI;
  302.    GET_EP(psc_ptr) = 0;
  303. }
  304. */
  305.  
  306. /************************************?????????????????????*********/
  307.  
  308. namestring(psc_ptr, s)
  309. PSC_REC_PTR psc_ptr;
  310. CHAR_PTR    s;
  311. {
  312.    LONG     i, len;
  313.    CHAR_PTR st;
  314.  
  315.    len = GET_LENGTH(psc_ptr);
  316.    st  = GET_NAME(psc_ptr);
  317.  
  318. #ifdef DEBUG_NAMESTRING
  319.    printf("namestring: len = %d    string = %s\n", len, st);
  320. #endif
  321.    for (i = 0; i < len; i++)
  322.       *s++ = *st++;
  323.    *s = '\0';
  324. }
  325.  
  326. /************************************?????????????????????*********/
  327.  
  328. LONG alloc_perm(size)   /* size should be a multiple of 4 */
  329. LONG size;
  330. {
  331.    LONG        addr;
  332.    PSC_REC_PTR psc_ptr;
  333.  
  334.    ALIGN(CHAR_PTR, curr_fence);
  335.    addr = (LONG)curr_fence;
  336.    psc_ptr = (PSC_REC_PTR)(curr_fence + 4);
  337.    *(LONG_PTR)curr_fence = (LONG)psc_ptr;  /* pt to psc record being created */
  338.    curr_fence += 12;                       /* no ep */
  339.    GET_ETYPE(psc_ptr)  = T_BUFF;
  340.    GET_ARITY(psc_ptr)  = 0;
  341.    GET_LENGTH(psc_ptr) = size;
  342.    GET_NAME(psc_ptr)   = curr_fence;
  343.    curr_fence += size;
  344.    ALIGN(CHAR_PTR, curr_fence);
  345.    if (curr_fence >= max_fence) {
  346. #ifdef DEBUG_OVERFLOW
  347.       printf("Overflow in \"alloc_perm\" curr_fence = %08x max_fence = %08x\n",
  348.              curr_fence, max_fence);
  349. #endif
  350.       quit("Program area overflow\n");
  351.    }
  352.    return addr;
  353. }  /* end of alloc_perm */
  354.